package org.tri.swing;

import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.BorderFactory;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

/**
 * La clase {@code EditableLabel} utiliza como componente editor un 
 * {@code JTextField} simple, permitiendo ingresar en el mismo cualquier tipo
 * de {@code String} que se desee.
 * @author kiira
 * @version 1.0, Feb 3, 2012
 */
public class EditableLabelTF extends AbstractEditableLabel<JTextField> {
       
    /**
     * {@inheritDoc}
     */
    @Override
    protected String preCheck( String text ) {
        editableComponent.setText( text );
        
        return text;
        
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void resetToDefault() {
        super.resetToDefault();
        
        ( (GridBagLayout)container.getLayout() ).setConstraints( this,
                                                                 constraints );
        
    }//end método resetToDefault   

    /**
     * {@inheritDoc}
     */
    @Override
    public void makeEditable( ) {
        //si el componente editable no fue inicializado, lo creamos
        if ( editableComponent == null )
            editableComponent = new JTextField();
               
        //seteamos un borde simple
        editableComponent.setBorder( 
                BorderFactory.createLineBorder( Color.black) );

        //llamamos al método de la clase padre
        super.makeEditable( );     

        ( (GridBagLayout)container.getLayout() ).setConstraints( this,
                                                                 constraints );
        //seteamos el texto actual del label al editor
        editableComponent.setText( getText() );
        
        //añadimos los listeners al textfield
        editableComponent.addKeyListener( new KeyHandler() );
        editableComponent.addFocusListener( new FocusHandler() );
                
    }//end método makeEditable

    /**
     * Comprueba si el textfield esta vacio y modifica las constraints de 
     * acuerdo a ello, de manera que si el label esta vacio, el text field se 
     * vea estirado horizontalmente para permitir escribir.
     */
    protected void checkEmptyTextField() {
        constraints.fill = ( editableComponent.getText().trim().length() == 0 )
                           ? GridBagConstraints.HORIZONTAL
                           : defaultFillValue;

    }//end método checkEmptyTextField

    /**
     * {@inheritDoc}
     */
    @Override
    public void deactivateEditMode() {
        //solo se desactiva si esta siendo editado
        if ( !isBeingEdited() )
            return;
        
        //remueve el textfield del contenedor
        container.remove( editableComponent );

        //obtiene el texto modificado
        String newText = editableComponent.getText();

        //y aplica la edición
        applyEdition( newText );
        
        //reincorporamos el label al contenedor
        container.add( this, constraints );

        container.revalidate();
        container.repaint();

    }//end método deactivateEditMode

    /**
     * {@inheritDoc}
     */
    @Override
    public void activateEditMode() {
        //solo se activa si NO esta siendo editado
        if ( isBeingEdited() )
            return;
               
        //removemos el label de container
        container.remove( this );

        //comprobamos si el textfield esta vacio y lo incorporamos al contenedor
        checkEmptyTextField();

        container.add( editableComponent, constraints );
        editableComponent.requestFocus();

        container.revalidate();
        container.repaint();

    }//end método activateEditMode

    /**
     * Handler que automáticamente agranda el textfield a medida que se va 
     * necesitando lugar, en el caso de que el mismo no este seteado en el
     * container para que ocupe todo el lugar disponible.
     */
    protected class KeyHandler extends KeyAdapter {

        /**
         * {@inheritDoc}
         */
        @Override
        public void keyTyped( KeyEvent e ) {
            //auto expandimos el text field si hace falta
            if ( constraints.fill == GridBagConstraints.NONE
                 || constraints.fill == GridBagConstraints.VERTICAL )
                container.revalidate();

        }//end método keyTyped

    }//end clase KeyHandler

    /**
     * Handler que selecciona todo el texto del textfield cuando el mismo
     * gana foco.
     */
    protected class FocusHandler implements FocusListener{

        /**
         * {@inheritDoc}
         */
        @Override
        public void focusGained( FocusEvent e ) {
            SwingUtilities.invokeLater( new Runnable() {

                @Override
                public void run() {
                    editableComponent.selectAll();
                    
                }
                
            });            

        }//end método focusGained

        /**
         * {@inheritDoc}
         */
        @Override
        public void focusLost( FocusEvent e ) {
            
        }//end método focusLost
                
    }//end clase FocusHandler

}//end clase EditableLabelTF